/**
 * @Author       : Mo 2427995270@qq.com
 * @Date         : 2025-07-28 21:44:24
 * @LastEditTime : 2025-07-31 00:45:13
 * @FilePath     : \ZN-1000-APP\hal_driver\ll_lptim.c
 * @Description  : 低功耗定时器低层驱动
 * @Version      : V1.0
 * @History      :
 * @Note         :
 */
/***************************************Includes***********************************/
#include "ll_lptim.h"

#if defined(GD32F407)
#include "gd32f4xx.h"
#elif defined(STM32F40_41xxx)
#include "stm32f4xx.h"
#elif defined(GD32F10X_HD)
#include "gd32f10x.h"
#elif defined(STM32F10X_HD)
#include "stm32f10x.h"
#elif defined(PY32F071xB)
#include "py32f0xx.h"
#else
#error "No device selected"
#endif

/************************************Private Macros********************************/

#define CLOCK_FREQ 32768
#define CLOCK_DIV 32


/**********************************Private Statement*******************************/


/***********************************Public Variables*******************************/



/**********************************Private Variables*******************************/

#if defined(PY32F071xB)
LPTIM_HandleTypeDef LPTIMConf;

#endif


/**********************************Public Functions********************************/

/**
 * @brief LPTIM时钟配置
 * @param  mode             事件或中断
 * @note null
 */
void lptim_clock_config(exti_ll_mode_t mode) {
#if defined(PY32F071xB)
    RCC_PeriphCLKInitTypeDef LPTIM_RCC = {0};
    LPTIM_RCC.PeriphClockSelection = RCC_PERIPHCLK_LPTIM;
    LPTIM_RCC.LptimClockSelection = RCC_LPTIMCLKSOURCE_LSE;
    if (HAL_RCCEx_PeriphCLKConfig(&LPTIM_RCC) != HAL_OK) {
        for (;;)
            ;
    }
    __HAL_RCC_LPTIM_CLK_ENABLE(); // 使能LPTIM时钟

    LPTIMConf.Instance = LPTIM1;
    LPTIMConf.Init.Prescaler = LPTIM_PRESCALER_DIV32;
    LPTIMConf.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
    if (HAL_LPTIM_Init(&LPTIMConf) != HAL_OK) {
        for (;;)
            ;
    }
    EXTI_ConfigTypeDef ExtiCfg = {0};
    EXTI_HandleTypeDef ExtiHandle = {0};
    ExtiCfg.Line = EXTI_LINE_29;
    ExtiCfg.Mode = mode == EXTI_LL_MODE_INTERRUPT ? EXTI_MODE_INTERRUPT : EXTI_MODE_EVENT;
    HAL_EXTI_SetConfigLine(&ExtiHandle, &ExtiCfg); // 配置LPTIM1中断线
    NVIC_SetPriority(TIM6_LPTIM1_DAC_IRQn, 0);
    NVIC_EnableIRQ(TIM6_LPTIM1_DAC_IRQn);
#else
#error "nonsupported device for LPTIM clock config"
#endif
}

/**
 * @brief 启动一次性定时器
 * @param  time_ms          定时时间，ms
 * @note null
 */
void lptim_start_once(uint32_t time_ms) {
    uint16_t period;
#if defined(PY32F071xB)
    __HAL_LPTIM_DISABLE(&LPTIMConf); // 禁止LPTIM
    if (time_ms > 64000) {
        period = 0xffff; // 超过64秒，设置为最大值
    } else {
        period = time_ms * (CLOCK_FREQ / 1000) / CLOCK_DIV; // LPTIM时钟为32768Hz，分频32
    }

    HAL_LPTIM_SetOnce_Start_IT(&LPTIMConf, period); // 设置一次性定时器
#else
#error "todo"
#endif
}
/**
 * @brief 启动连续定时器
 * @param  time_ms          定时时间，ms
 * @note null
 */
void lptim_start_continue(uint32_t time_ms) {
    uint16_t period;
#if defined(PY32F071xB)
    __HAL_LPTIM_DISABLE(&LPTIMConf); // 禁止LPTIM
    if (time_ms > 64000) {
        period = 0xffff; // 超过64秒，设置为最大值
    } else {
        period = time_ms * (32768 / 1000) / 32; // LPTIM时钟为32768Hz，分频32
    }

    HAL_LPTIM_SetContinue_Start_IT(&LPTIMConf, period); // 设置连续定时器
#else
#error "todo"
#endif
}
/**
 * @brief 停止连续定时器
 * @note null
 */
void lptim_stop_continue(void) {
#if defined(PY32F071xB)
    HAL_LPTIM_SetContinue_Stop_IT(&LPTIMConf); // 停止连续定时器
#else
#error "todo"
#endif
}
/**
 * @brief 获取当前计数时间 ms
 * @return uint32_t ms
 * @note null
 */
uint32_t lptim_get_counter_time(void) {
    uint32_t time = 0;
#if defined(PY32F071xB)
    time = HAL_LPTIM_ReadCounter(&LPTIMConf) * CLOCK_DIV * 1000 / CLOCK_FREQ; // LPTIM时钟为32768Hz，分频32
#else
#error "todo"
#endif
    return time;
}

/**********************************Private Functions*******************************/

#if defined(PY32F071xB)
void TIM6_LPTIM1_DAC_IRQHandler(void) {
    HAL_LPTIM_IRQHandler(&LPTIMConf);
}
#else
#error "todo"
#endif

/* [] END OF FILE */
